# 作者： 迷路的小怪兽
# 创建时间： 2021/11/21 23:06
import os
import configparser as parser
import xlrd
import openpyxl
import demjson
from src.common.getlog import MyLog

# 日志重复的问题需要解决！！！！


class OperationINI:

    # 初始化配置文件路径
    def __init__(self, file_path=None):
        if file_path is not None:
            self.file_dir = file_path
        else:
            self.dir = os.path.dirname(os.path.abspath(__file__)).split('auto-test-project')[0]
            self.file_dir = os.path.join(self.dir, 'auto-test-project\\data\\data_config.ini')
        self.config = parser.ConfigParser()
        self.config.read(self.file_dir, encoding='utf-8')

    # 获取用例ID的列数
    def get_case_id_num(self):
        case_id = self.config.get('excel_fields', 'case_id')
        return int(case_id)

    # 获取用例名称的列数
    def get_case_name_num(self):
        case_name = self.config.get('excel_fields', 'case_name')
        return int(case_name)

    # 获取请求URL的列数
    def get_url_num(self):
        url = self.config.get('excel_fields', 'url')
        return int(url)

    # 获取请求方法的列数
    def get_request_method_num(self):
        request_method = self.config.get('excel_fields', 'request_method')
        return int(request_method)

    # 获取是否携带header的列数
    def get_has_header_num(self):
        has_header = self.config.get('excel_fields', 'has_header')
        return int(has_header)

    # 获取是否执行的列数
    def get_is_run_num(self):
        is_run = self.config.get('excel_fields', 'is_run')
        return int(is_run)

    # 获取case依赖的列数
    def get_case_depend_num(self):
        case_depend = self.config.get('excel_fields', 'case_depend')
        return int(case_depend)

    # 获取依赖的响应字段的列数
    def get_response_field_num(self):
        response_field = self.config.get('excel_fields', 'response_filed')
        return int(response_field)

    # 获取依赖的数据请求字段的列数
    def get_request_field_num(self):
        request_field = self.config.get('excel_fields', 'request_field')
        return int(request_field)

    # 获取请求数据的列数
    def get_request_data_num(self):
        request_data = self.config.get('excel_fields', 'request_data')
        return int(request_data)

    # 获取预期结果的列数
    def get_expect_result_num(self):
        expect_result = self.config.get('excel_fields', 'expect_result')
        return int(expect_result)

    # 获取实际结果的列数
    def get_current_result_num(self):
        current_result = self.config.get('excel_fields', 'current_result')
        return int(current_result)

    # 获取用例执行结果的列数
    def get_result_num(self):
        result = self.config.get('excel_fields', 'result')
        return int(result)

    # 获取用例执行日期的列数
    def get_date_num(self):
        date = self.config.get('excel_fields', 'date')
        return int(date)


class OperationExcel:

    # 初始化读取Excel表格,实例化操作ini的类
    def __init__(self, file_path=None):
        if file_path is not None:
            self.file_dir = file_path
        else:
            self.dir = os.path.dirname(os.path.abspath(__file__)).split('auto-test-project')[0]
            self.file_dir = os.path.join(self.dir, 'auto-test-project\\data\\data.xlsx')
        # 打开用例Excel文件（读取用）
        self.work_book = xlrd.open_workbook(self.file_dir)
        self.sheet = self.work_book.sheet_by_name('case')
        # 打开用例Excel文件（写结果用），可以只用openpyxl模块
        self.work_book_w = openpyxl.load_workbook(self.file_dir)
        self.sheet_w = self.work_book_w.active
        # 初始化读取配置文件的类
        self.opt_ini = OperationINI()
        self.opt_json = OperationJson()
        # 初始化日志写入
        self.log = MyLog()
        # 初始化每个字段的列数
        self.case_id = self.opt_ini.get_case_id_num()
        self.case_name = self.opt_ini.get_case_name_num()
        self.url = self.opt_ini.get_url_num()
        self.request_method = self.opt_ini.get_request_method_num()
        self.has_header = self.opt_ini.get_has_header_num()
        self.is_run = self.opt_ini.get_is_run_num()
        self.case_depend = self.opt_ini.get_case_depend_num()
        self.response_field = self.opt_ini.get_response_field_num()
        self.request_field = self.opt_ini.get_request_field_num()
        self.request_data = self.opt_ini.get_request_data_num()
        self.expect_result = self.opt_ini.get_expect_result_num()
        self.current_result = self.opt_ini.get_current_result_num()
        self.result = self.opt_ini.get_result_num()
        self.date = self.opt_ini.get_date_num()

    # 获取用例条数
    def get_case_num(self):
        return self.sheet.nrows

    # 获取用例ID
    def get_case_id(self, row):
        return self.sheet.cell_value(row, self.case_id)

    # 获取用例名称
    def get_case_name(self, row):
        return self.sheet.cell_value(row, self.case_name)

    # 获取URL
    def get_url(self, row):
        return self.sheet.cell_value(row, self.url)

    # 获取请求方法
    def get_request_method(self, row):
        return self.sheet.cell_value(row, self.request_method)

    # 获取是否携带header
    def get_has_header(self, row):
        return self.sheet.cell_value(row, self.has_header)

    # 获取是否执行
    def get_is_run(self, row):
        return self.sheet.cell_value(row, self.is_run)

    # 获取用例依赖
    def get_case_depend(self, row):
        return self.sheet.cell_value(row, self.case_depend)

    # 获取依赖的响应字段
    def get_response_field(self, row):
        return self.sheet.cell_value(row, self.response_field)

    # 获取依赖数据请求的字段
    def get_request_field(self, row):
        return self.sheet.cell_value(row, self.request_field)

    # 获取请求数据
    def get_request_data(self, row):
        data_field = self.sheet.cell_value(row, self.request_data)
        return self.opt_json.get_data_from_json(data_field)

    # 获取预期结果
    def get_expect_result(self, row):
        return self.sheet.cell_value(row, self.expect_result)

    # 获取实际结果
    def get_current_result(self, row):
        return self.sheet.cell_value(row, self.current_result)

    # 获取执行结果
    def get_result(self, row):
        return self.sheet.cell_value(row, self.result)

    # 获取执行日期
    def get_date(self, row):
        return self.sheet.cell_value(row, self.date)

    # 获取某一行的所有数据,由于data值需要重新调用接收的值，所以不能直接用row_value方法
    def get_row_data(self, row):
        if self.get_case_id(row):
            data_list = [self.get_case_id(row),
                         self.get_case_name(row),
                         self.get_url(row),
                         self.get_request_method(row),
                         self.get_has_header(row),
                         self.get_is_run(row),
                         self.get_case_depend(row),
                         self.get_response_field(row),
                         self.get_request_field(row),
                         self.get_request_data(row),
                         self.get_expect_result(row)]
            self.log.info('获取用例id为 %d 行的数据成功！' % self.get_case_id(row))
            return data_list
        else:
            self.log.info('用例id为 %d 不存在或数据为空！' % self.get_case_id(row))
            return []

    # 获取某一列的所有数据
    def get_col_data(self, col=None):
        if col is not None:
            data_list = list(self.sheet.col_values(col, start_rowx=1))
            self.log.info('获取第 %s 列数据成功！' % str(col + 1))
        else:
            data_list = list(self.sheet.col_values(0, start_rowx=1))
            self.log.info('获取第 1 列数据成功！')

        return data_list

    # 往某一单元格写值（字符串）::注意，这里的行列起始为1不是0，xlrd是由0开始，因此代码中需要处理
    def write_into_cell(self, row, col, value):
        self.sheet_w.cell(row+1, col+1, value)
        self.work_book_w.save(self.file_dir)
        # self.log.debug('%s 行 %s 列数据写入成功！' %(str(row+1), str(col+1)))

    # 写入用例实际结果
    def add_current_result(self, row, current_result):
        self.write_into_cell(row, self.current_result, str(current_result))
        self.log.debug('%s 行用例实际返回值已写入！' % str(row))

    # 写入用例执行结果
    def add_result(self, row, result):
        self.write_into_cell(row, self.result, result)
        self.log.debug('%s 行用例执行结果已写入！' % str(row))

    # 写入用例执行日期
    def add_date(self, row, date):
        self.write_into_cell(row, self.date, date)
        self.log.debug('%s 行用例执行日期已写入！' % str(row))


class OperationJson:

    def __init__(self, file_path=None):
        self.log = MyLog()
        if file_path is not None:
            self.file_path = file_path
        else:
            self.file_path = os.path.join(os.path.dirname(os.path.abspath(__file__)).split('auto-test-project')[0],
                                          'auto-test-project\\data\\requests_data_model.json')

    # 从json文件中获取某一字段的值，使用demjson简单很多（decode_file是吧json文件解析成字典，encode_to_file相反）
    def get_data_from_json(self, field):
        data_source = demjson.decode_file(self.file_path)
        data = data_source[field]
        self.log.debug('%s 数据已从json文件中读取成功！' % field)
        return data